package com.ruoyi.web.controller.common;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.UserAgent;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.io.*;
import javax.servlet.http.*;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;


import javax.servlet.http.HttpServletRequest;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class Common {
    public  static  String ConfigFile="./javaconfig.txt";
    //public  static  String SysTitle=getConfig("SysTitle"),SysSwitch=getConfig("SysSwitch"),UploadPath=getConfig("UploadPath"),xygLogFile=getConfig("xygLogFile");
    public  static  String SysTitle,SysSwitch,UploadPath,xygLogFile;

    /// <summary>
    /// 作用：公共分页方法（并未过滤sql危险字符，使用需谨慎，拼凑sql时，可自行过滤sql危险字符，另：支持多表联查）
    /// 作者：叶端
    /// </summary>
    /// <param name="model">传入分页实体</param>
    /// <param name="Count">根据条件，返回总条数</param>
    /// <returns></returns>
    public static List<Map<String, Object>> DbPageFunc(PageModel entity) {
        //获得需查询截止的条数
        int number = (entity.Page - 1) * entity.Top;
        String sqlx1 = "列表序号X";

        //如果传入的字段为null或者""，则赋默认值*
        if (entity.Field == null || entity.Field .equals("")) entity.Field = "*";
        //if (!entity.Table.toLowerCase().contains(" join")) entity.Table += "  ";//如果没有多表关联则加上脏读谢益祥2014年9月29日17:44:47
        //拼接sql语句，并未过滤,条件需自行过滤 oracle 分页
        String sql = "select * from (select ROWNUM " + sqlx1 + "," + entity.Field + " from " + entity.Table + " where 1=1 " + entity.Where + entity.Order + ") a where " + sqlx1 + " between " + number + " and " + (number + entity.Top) + " order by " + sqlx1;
        if(SysSwitch.contains("mysql")) sql = "select " + entity.Field + " from " + entity.Table + " where 1=1 " + entity.Where +" "+ entity.Order + " limit " + number + " , " + entity.Top + " ";//mysql分页
        //System.out.println(sql);
        //统计sql，此处如果要优化，可以增加统计表，或将 count（*）变成count（主键），这样统计速度会增加
        String countSql = "select count(*) from " + entity.Table + "  where 1=1 " + entity.Where;
        entity.RecCnt = Integer.valueOf(JdbcSql.GetSHSL(countSql));
        try {

        } catch (Exception e) {
            entity.RecCnt = 0;
        }        //统计条数        WriteXYGLogInFile(sql);
        //进行查询
        return JdbcSql.GetDataSet(sql);
    }

    /// <summary>
    /// 把DataTable的数据转换为json对象
    /// </summary>
    /// <param name="uc">数据表datatable</param>
    /// <returns></returns>
    public static String DataTable2Json(List<Map<String, Object>> dt) {
        if (dt == null) return "[]";
        StringBuilder jsonBuilder = new StringBuilder();
        String str1 = "";
        jsonBuilder.append("[");
        for (int i = 0; i < dt.size(); i++) {
            jsonBuilder.append("{");
            for (String key : dt.get(0).keySet()) {
                jsonBuilder.append("\"");
                jsonBuilder.append(key);
                jsonBuilder.append("\":\"");
                Object Val = dt.get(i).get(key);
                String Vs = "";
                if (Val != null) Vs = Val.toString();
                jsonBuilder.append(Vs.replace("\\", "\\\\").replace("\'", "'").replace("\0", "").replace("\t", " ")
                        .replace("\r", " ").replace("\n", "<br/>").replace("\"", "'"));
                //.replace("\r", " ").replace("\n", "<br/>").replace("\"", "'").replace("\t", " "));//json去除特殊字符:回车换行符
                //System.Web.HttpContext.Current.Response.Write(dt.Rows[i][j].toString());//如果是开发人员,打印sql出来
                jsonBuilder.append("\",");
            }
            //jsonBuilder.delete(jsonBuilder.length() - 1, 1);
            jsonBuilder.deleteCharAt(jsonBuilder.length() - 1);
            jsonBuilder.append("},");
        }
        //jsonBuilder.delete(jsonBuilder.length() - 1, 1);
        jsonBuilder.deleteCharAt(jsonBuilder.length() - 1);
        jsonBuilder.append("]");
        str1 = jsonBuilder.toString();
        if (str1.length() == 1) str1 = "[]";//2018年4月15日 17:54:40谢益祥改为[],之前是空,但是返回json有问题
        //if (Utf8Rquest("DesEncJson") == "1") return "\"" + LJX.Common.DEncrypt.DESEncrypt.encMeDes(str1, "xieyixiang1688") + "\"";//谢益祥2020年6月10日 14:35:02对于h5+ashx的模式,对数据进行加密,避免被直接破解转移数据
        return str1;
    }

    /// <summary>
    ///獲取一個字符串中指定字符之間的字符串
    /// </summary>
    public static String GetStrBetween(String str, String sStart, String sEnd) {
        //判斷要截取的字符串是否是數組和字母的組合
        int firstIndex = str.indexOf(sStart, 0);
        int secondIndex = str.indexOf(sEnd, firstIndex + sStart.length() + 1);
        if (firstIndex < 0 || secondIndex < 0) return "";
        String childStr = str.substring(firstIndex + sStart.length(), secondIndex);// - (firstIndex + sStart.length())
        return childStr;
    }
    public static boolean isDate(String str,String DateFormat) {//"yyyy/MM/dd HH:mm"
        boolean convertSuccess = true;
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写； //如果想判断格式为yyyy-MM-dd，需要写成-分隔符的形式
        SimpleDateFormat format = new SimpleDateFormat(DateFormat);
        try {

            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            // 如果抛出ParseException或者NullPointerException，就说明格式不对
            convertSuccess = false;
        }
        return convertSuccess;
    }
    public static Boolean IsNumericExpXLs(String value)//xls导出用,逗号分隔的数字也是数字,但是094583不是数字,但是0.32是数字,[123.4532,3432]不是数字
    {
        String Val00 = value.replace(",", ""), val1 = value.replace(",", "").replace(".", "").replace("0", "");
        String[] ar = value.split("\\.");
        if (ar.length > 2) return false;//如果有两个小数点,则不为数字
        if (ar.length == 2 && ar[1].contains(",")) return false;//如果小数点位,有逗号,则不为数字
        if (ar[0].length() > 1 && ar[0].substring(0, 1).equals("0")) return false;//094583不是数字
        if (IsIdentityCard(value)) return false;
        Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
        return pattern.matcher(Val00).matches();
    }

    /// <summary>
    /// 验证身份证
    /// </summary>
    /// <param name="txt"></param>
    /// <returns></returns>
    public static Boolean IsIdentityCard(String txt) {
        Pattern objReg = Pattern.compile("^(^\\d{18}$|^\\d{17}(\\d|X|x))$");
        return objReg.matcher(txt).matches();
    }

    public String MD5Encrypt(String pToEncrypt) {
        return DigestUtils.md5DigestAsHex(pToEncrypt.getBytes());
    }//MD5加密

    /// <summary>
    /// 分析用户请求是否正常
    /// </summary>
    /// <param name="Str">传入用户提交数据</param>
    /// <returns>返回是否含有SQL注入式攻击代码</returns>
    //检查是否有sql注入
    public static boolean sql_Injection(String str) {
        String inj_str = "' and exec insert select delete update count * % chr mid master truncate char declare ; or - + ,";
        String arr[] = inj_str.split(" ");
        for (int i = 0; i < arr.length; i++) {
            if (str.indexOf(arr[i]) != -1) {
                //response.Write("<script>alert('检测到SQL注入攻击，你可能构成非法侵入计算机信息系统罪，系统已经留存你的IP和操作日志作为违法行为证据，本单位可能向网络警察报警并提交你的违法行为证据，请马上停止入侵行为！');</script>");//返回页面
                return true;
            }
        }
        return false;
    }

    //    public static Boolean StartProcessRequest()
//    {
//        try
//        {
//            String getkeys = "";
//            String sqlErrorPage = request.getContextPath() + "/default.aspx";
//            if (request.getQueryString() != null)
//            {
//
//                for (int i = 0; i < request.getQueryString().length(); i++)
//                {
//                    getkeys = request.getQueryString()..Keys[i];
//                    String qri = System.Web.HttpUtility.UrlDecode(request.getQueryString()[getkeys].toLowerCase(), Encoding.GetEncoding("UTF-8"));//进行unescape,把中文和空格反算出来xyx2019年9月17日 09:51:46
//                    if (JdbcSql.ifUrlSqlInject(qri))
//                    {
//                        System.Web.HttpContext.Current.Response.Write("<script>alert('检测到SQL注入攻击，你可能构成非法侵入计算机信息系统罪，系统已经留存你的IP和操作日志作为违法行为证据，本单位可能向网络警察报警并提交你的违法行为证据，请马上停止入侵行为！');</script>");//返回页面
//                        System.Web.HttpContext.Current.Response.End();
//                        return true;
//                    }
//                }
//            }
//            String strUrl = System.Web.HttpContext.Current.Request.Url.AbsolutePath, strPage = "";
//            strPage = strUrl.split('/')[strUrl.split('/').Length - 1].replace(".aspx", "");
//        }
//        catch { }
//        return false;
//    }
    public static void WriteXYGLogInFile(String content) {
        try (FileWriter fileWriter = new FileWriter(xygLogFile,true)) {
            fileWriter.append("\n[" + getDatetime() + "]" + content);
        } catch (Exception e) {
        }
    }

    public static String SessionGet(String Key) {
        String Value = "";
        try {
            HttpSession session = getRequest().getSession();
            if(Key.equals("UserName")&&session.getAttribute(Key)==null){return  Utf8Rquest("UserId");}
            //{Common.ResponseWrite("{\"errormsg\":\"会话不存在\"}");return  "";}
            Value = session.getAttribute(Key).toString();
        } catch (Exception e) {
            //return  "";
        }
        return Value;
    }

    public static void SessionSet(String Key, String Value) {
        try {
            HttpSession session = getRequest().getSession();
            session.setAttribute(Key, Value);
        } catch (Exception e) {
        }
    }

    /**
     * 获取 HttpServletRequest
     *
     * @author gourd
     * @date 2018-11-24
     */
    public static String Encrypt(String s, String Key) {
        return s;
    }

    public static String Decrypt(String s) {
        return s;
    }

    public static boolean isStrEmpty(String s) {
        if (s == null || s .equals("")) return true;
        return false;
    }
    public static String PageLimit() {//判断URL的是否有权限访问 以及是否离线//返回页面权限列表  成功返回:页面权限 失败返回空
        if (1==1||getRequest().getRequestURI()=="") return "\"all\"";///oa-erp/WgBnfShareRule/Get
        if(isStrEmpty(SessionGet("username"))) Common.ResponseWrite ("{\"errormsg\":\"已经离线\"");
        else Common.ResponseWrite ("{\"errormsg\":\"无权进入\"");
        return "";
    }

    public static String Utf8Rquest(String s) {
        //return URLDecoder.decode((getRequest()[s] ? ? ""),"UTF-8").replace("2b.8x", "+");
        String rst = "";
        //解决get请求中文乱码问题
        rst = getRequest().getParameter(s);
        if(s.contains("ddl")&&rst==null)rst = getRequest().getParameter(s.replace("ddl","h"));
        if (!isStrEmpty(rst)) rst = rst.replace("2b.8x", "+");
        else rst = "";
        return rst;
    }

    public static void ResponseWrite(String s) {//类似于response.write
        //CommonResponse.success(s); if(1==1)return;
        //getResponse().setHeader("Access-Control-Allow-Origin","http://127.0.0.1");//没用,现在用ngix跨域实现了
        getResponse().setContentType("text/html;charset=utf-8");
        PrintWriter out = null;
        try {
            out = getResponse().getWriter();
            out.write(s);
            // 强制将缓冲区中的数据发送出去,不必等到缓冲区满
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }
    public static String getDatetime(){
        String TimeNow = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS").format(Calendar.getInstance().getTime());
        return TimeNow;
    }
    public static HttpServletRequest getRequest() {//获取Request对象
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return req;
    }

    public static HttpServletResponse getResponse() {//获取Response对象
        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        resp.setHeader("Access-Control-Allow-Origin", "*");
        return resp;
    }

    /**
     * 删除字符串首尾指定字符
     */
    public static String Trim(String str, String c) {
        if(isStrEmpty(str)||str.length()<=c.length())return  str;
       if(str.substring(0,c.length()).equals(c)) str=str.substring(c.length());
        if(isStrEmpty(str)||str.length()<=c.length()||str.lastIndexOf(c)!=str.length()-1)return  str;
        return str.substring(0,str.lastIndexOf(c));
    }

    public static void WriteRizhi(String content, int MenuID) {
        String UserName = SessionGet("UserName");
        String IpStr = getIpAddr();
        JdbcSql.ExecuteSQL("insert into XOARiZhi(UserName,DoSomething,IpStr,MenuID) select '" + UserName + "','" + content + "','" + IpStr + "','" + MenuID + "' from dual");
    }
    public static String browserName(){
        String userAgent = getRequest().getHeader("User-Agent");
        UserAgent ua = UserAgent.parseUserAgentString(userAgent);
        Browser browser = ua.getBrowser();
        return browser.getName() + "-" + browser.getVersion(userAgent);
    }
    /**
     * 获取客户端IP
     */
    public static String getIpAddr() {
        String ip = getRequest().getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = getRequest().getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = getRequest().getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = getRequest().getRemoteAddr();
        }
        return ip;

    }
    /**
     * 根据传入的虚拟路径获取物理路径
     *
     * @param path
     * @return
     */
    public static String getPhysicalPath(String path) {
        String servletPath = getRequest().getServletPath();
        String realPath = getRequest().getSession().getServletContext()
                .getRealPath(servletPath);
        return new File(realPath).getParent() + "/" + path;
    }
    /// <summary>
    /// 字符串数组去重,比如 1,2,1,3 返回 1,2,3
    /// </summary>
    /// <param name="S"></param>
    /// <returns></returns>

    public static String StrArrayNoDup(String S)
    {
        String[] a = S.split(",");
        String b = ",";//用于isNumberic存储已取出的元素
        String newa = ""; ;
        int j = 0;
        for (int i = 0; i < a.length; i++)
        {
            if (b.indexOf("," + a[i] + ",") == -1)
            {
                //此时可以提取元素
                newa += a[i] + ",";
                b = b + a[i] + ",";
                j++;
            }
        }
        if(newa.equals("")) return  "";
        return newa.substring(0,newa.length()-1);
    }
    public class DemoData {
        private String String;
        private Date date;
        private Double doubleData;
    }

    protected static boolean isNumberic(String str,int type)//是否数字 type 1整数  2小数点
    {
        try {
            // parseInt 是将字符串转换为整数类型，返回一个int类型，如果字符串中有非数字类型字符，则会抛出一个NumberFormatException的异常
          if(type==1)  Integer.parseInt(str);
          else if(type==2)  Float.parseFloat(str);
            return true;
        } catch (NumberFormatException e) {
            //e.printStackTrace();
            return false;
        }
        }
    public static String AshxPostInputStr()//C#直接接收Post参数(用数据流)
    {

            return "";
    }
    /// <summary>
    /// //获取可以访问的flow的脚本
    /// </summary>
    public static String getCanUseFlowSql()
    {
        return " ( ( ( (a.DepListOK='全部' or IFStrPartIn(DepListOK,GetDeptPathByDeptID('" + SessionGet("deptid")
                + "'))='1') and ( a.JiaoSeListOK='全部' or IFStrPartIn('," + SessionGet("ZhiWei") + ",',JiaoSeListOK)='1' ) )  or CHARINDEX(',"
                + SessionGet("UserName") + ",',','+UserListOK+',')>0 ) "
                + "and ( ifnull(a.DepListNo,'')='' or IFStrPartIn('," + SessionGet("deptid") + ",',DepListNo)!='1' ) "
                + "and ( ifnull(a.JiaoSeListNo,'')='' or IFStrPartIn('," + SessionGet("ZhiWei") + ",',JiaoSeListNo)!='1' ) "
                + "and ( ifnull(a.UserListNo,'')='' or IFStrPartIn('," + SessionGet("UserName") + ",',UserListNo)!='1' ) "
                + ")";
    }
    public static String getConfig(String Key)  {//所有获取配置的,类似于webconfig
//        if(Key.equals("SysSwitch"))   return WebConfigurer.SysSwitch;
//        if(Key.equals("UploadPath"))   return WebConfigurer.UploadPath;
//        if(Key.equals("SysTitle"))   return WebConfigurer.SysTitle;
//        if(Key.equals("xygLogFile"))   return WebConfigurer.xygLogFile;
        Properties prop = new Properties();
           try {
                   InputStream InputStream = new BufferedInputStream(new FileInputStream(new File(ConfigFile)));// 通过输入缓冲流进行读取配置文件
                    InputStreamReader isr = new InputStreamReader(InputStream, "UTF-8");
                    BufferedReader br = new BufferedReader(isr);
                   prop.load(br);// 加载输入流
               return prop.getProperty(Key); // 根据关键字获取value值
               } catch (Exception e) { e.printStackTrace(); }
           return "";
    }


    public static String get登录密级()//获取登录密级 1简单 2字母+数字 3:2+特殊字符
    {
        String PwdLevel = getConfig("SysSwitch") ;
        if(1==1) return  "1";
        if (!PwdLevel.contains("登录密级")) PwdLevel = "|登录密级3|";
        return ( GetStrBetween(PwdLevel, "登录密级", "|"));
    }
    public static String PubUserLoginFunc(Map<String, Object> row, String LoginType)
    {
        UUID uuid = UUID.randomUUID();
        String SqlSTr = "", SessId = uuid.toString(), deptid = row.get("deptid").toString().trim(), Org1 = "", AllOrg = "";
        if (deptid .equals( "-1")|| deptid .equals( "0") || deptid .equals("")) { return  "错误:该用户所在部门已失效，请联系管理员！";}
        PubUserLoginSetSess(row, SessId);//设置Session的各个值
        //写登录日志 
        JdbcSql.ExecuteSQL("update xoauser set SessionId='" + SessId + "',ActiveTime=now(),POP3Server='"+getIpAddr()+"' where username=" + row.get("UserName").toString() + " and state=1;");
        JdbcSql.ExecuteSQL("insert into XOARiZhi(UserName,DoSomething,IpStr) select " + row.get("UserName").toString() + ",'用户登录系统','" + getIpAddr() + "'");

//        String 角色可见部门 = JdbcSql.GetStringList("SELECT 默认可见部门 FROM XOAJiaoSe WHERE 默认可见部门!='' AND CHARINDEX(','+JiaoSeName+',' , '," + row["JiaoSe"].toString() + ",')>0 ").replace("|", ",").trim(','),orgJ="";
//        orgJ = Common.rjGetFgs(LJX.Common.FuncPubX.SessionGet("DeptParents"), 角色可见部门);
//        BusTypeView["orgviewinit"] = JdbcSql.GetSHSL("select org from BSSUserViewOrg where state=1 and username=" + row.get("UserName").toString());//初始化可以看到的值
//        Org1 = JdbcSql.GetStringList("select id from xoabumen where state=1 and ','+chargeman+',' like '," + row.get("UserName").toString() + ",'").replace("|", ",");
//        AllOrg = LJX.Common.FuncPubX.SessionGet("deptid") + "," + BusTypeView["orgviewinit"].toString() + "," + Org1 + (orgJ .equals("") ? "" : "," + orgJ);
//        BusTypeView["orgviewmax"] = JdbcSql.GetStringList(@"SELECT  ID FROM  XOABuMen WHERE  state=1 AND ID IN (SELECT  a FROM    splitStr2Tab('" + AllOrg
//            + "',',')) AND LEVEL=(SELECT MIN(LEVEL) FROM   XOABuMen WHERE  state=1 AND ID IN (SELECT  a FROM    splitStr2Tab('" + AllOrg + "',','))) ").replace("|", ",").trim(',');//用户能够见到的最高级的部门id
//        System.Web.HttpContext.Current.Session["orgview"] = JdbcSql.GetSHSL("select [GetChildDeptByDeptID]('" + LJX.Common.FuncPubX.SessionGet("deptid") + "," + BusTypeView["orgviewinit"].toString() + "," + Org1
//                + "')").trimStart(',').trimEnd(',');//使用session来存储可见部门

        //weixin 微信登录//目前测试发现Android手机微信的登录login返回给前端的json,可能会被这里影响,所以此处改为返回参数给wx的ashx 2018年7月24日 10:55:50xyx
        return "成功登录";
    }
    public static String creGuid()//算法生成的二进制长度为128位的数字标识符 guid
    {
        return UUID.randomUUID().toString();
    }
    public static Boolean StrContainList(String InitStr, String ContainList)//字符串包含另外几个
    {
        String[] ar = ContainList.split("^");
        if (!ContainList.contains("^")) ar = ContainList.split(",");
        for (int i = 0; i < ar.length; i++)
        {
            if (("," + InitStr + ",").contains("," + ar[i] + ",")) return true;
        }
        return false;
    }
    public static String PubUserLoginSetSess(Map<String, Object> row, String SessId)//设置Session的各个值xyx 2021年3月20日 10:42:09
    {
        String SqlSTr = "";
        SessionSet("UserID", row.get("UserName").toString());
        SessionSet("UserName", row.get("UserName").toString());
        SessionSet("JiaoSe", row.get("JiaoSe").toString());
        SessionSet("Department", row.get("Department").toString());
        SessionSet("TrueName", row.get("TrueName1").toString());
        SessionSet("deptid", row.get("deptid").toString());
        //SessionSet("buid", row.get("buid").toString());
        SessionSet("ZhiWei", row.get("ZhiWei").toString() + "," + Trim(row.get("rlgangwei").toString(),","));
        SessionSet("Gangwei", row.get("rlgangwei").toString());
        //SessionSet("DaoHangList", row.get("DaoHangList").toString());
        SessionSet("DeptParents", row.get("DeptParents").toString());
        //SessionSet("EcId", row.get("EcId").toString());
        SessionSet("serils", row.get("serils").toString());
        SessionSet("MobileFlag", row.get("isHandLogin").toString());//是否手势登录,科院=是否允许微信登录2022年1月5日 11:17:16xyx
        SessionSet("SessionId", SessId);//加入唯一终端登录:1.登录的时候写入SessionId  2.此处获取SessionId=自己并且登录时间在5分钟内,否则就退出
        SessionSet("funcflag", row.get("funcflag").toString()); //Response.Redirect("Main/Menu.aspx?ID=1")); }
        if (!row.get("JiaoSe").toString().contains("超级管理员")) SqlSTr = JdbcSql.GetStringList("select QuanXian from XOAJiaoSe where JiaoSeName in(" + "'" + row.get("JiaoSe").toString().replace(",", "','") + "'" + ")") + "|" + row.get("limits").toString();//xyx 2013年11月24日0:44:11缩减权限所占空间
        SessionSet("QuanXian", "|" + StrArrayNoDup(SqlSTr.replace("|", ",")).replace(",", "|") + "|");
        return "成功登录";
    }
    //单点登录某个页面
    public static String SsoUserLogin(String UserName, String Sn, String timestamp)//设置Session的各个值xyx 2021年3月20日 10:42:09
    {   //用于跟app衔接,app端传入deviceid进行匹配; 加入校验串,避免被黑客了.
        if (!timestamp.equals("") && !VerTokenDev()) { return  "错误:非法登录！可能的原因：1、您长时间未操作；2、您的账号在另一地方登录。"; }
        String SessId = UUID.randomUUID().toString(), query = "select top 1 username id,mobile phone,truename truename,ifnull(isHandLogin,0) isHandLogin,ifnull( 是否后备人才,0) 是否后备人才,Department,deptid,FuJian,funcflag,Serils,GetCodeNameByIDNew('rzCode','性别',Sex) Sex,ifnull(XueLi,3) XueLi,JiaoSe,"
            +"1 EcId,username,state,UserPwd,IfLogin,buid,ZhiWei,rlgangwei,DaoHangList,ifnull(MenuStyle,0) MenuStyle1,limits,funcflag,ifnull(getusernamebyid(username),truename) TrueName1,"
            +"GetDeptPathByDeptID(deptid) DeptParents ,zhiweiname,-1*datediff(mi,ifnull(允许登录时间,getdate()),getdate()) 允许登录时间差,ifnull(登录错数,0) 登录错数,rzState from XOAUser where  state=1 and username=" + UserName;
        Map<String, Object> dr1 = JdbcSql.GetDbRow(query);
        return PubUserLoginSetSess(dr1, SessId);
    }
    //@public static RedisHelper rh = new RedisHelper();
    public static boolean VerTokenDev()//读取会话表的记录,写入日志
    {
        return true;
        //@Map<Object, Object> r1 = rh.hmget(rh.RedisDefaultKey + "login" + Common.Utf8Rquest("UserId"));// dtAppLoginSess.Get((context.Request["UserId"] ?? ""));
        //@return (r1 != null && (r1.get("token") .equals( Common.Utf8Rquest("token")) && r1.get("deviceid") .equals( Common.Utf8Rquest("deviceid"))));
    }
    public static boolean IsMobilePhone(String str) throws PatternSyntaxException {
        // ^ 匹配输入字符串开始的位置
        // \d 匹配一个或多个数字，其中 \ 要转义，所以是 \\d
        // $ 匹配输入字符串结尾的位置
        if(str.length()!=11) return  false;
        String regExp = "^((1[0-9]))\\d{9}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(str);
        return m.matches();
    }
    /// 登录系统LoginType 1:用username,2用serils 真正的用户名 wx
    /// </summary>
    /// <param name="MyUserName"></param>
    /// <param name="MyUserPwd"></param>
    public static String UserLogin(String MyUserName, String MyUserPwd, String PwdLvl/*密码等级*/, String LoginType/*方式*/)
    {//支持工号,手机号,姓名,微信号
        String sql = "select Serils,state,UserPwd,IfLogin,ID,UserName,EcId EcId,JiaoSe,ifnull(Department,'') Department,deptid,buid,ifnull(ZhiWei,'') ZhiWei,rlgangwei,DaoHangList,ifnull(MenuStyle,0) MenuStyle1,ifnull(limits,'') limits," +
                "funcflag,ifnull(getusernamebyid(username),truename) TrueName1,ifnull(isHandLogin,0) isHandLogin,"
            +"0 DeptParents ,zhiweiname,0 允许登录时间差,ifnull(登录错数,0) 登录错数,rzState from XOAUser where state in (1,3)";
        String SqlSTr = sql + " and UserName='" + MyUserName + "' and state=1";
        if (MyUserName.contains("'") || MyUserName.contains(" or ")) { return "错误:登录名非法"; }
        if (LoginType.contains("username")) SqlSTr = SqlSTr + " and username='" + MyUserName + "'";
        else if (LoginType.contains("2") || IsMobilePhone(MyUserName) || (isNumberic(MyUserName,1) && MyUserName.length()>6)) SqlSTr = sql + " and (Serils='" + (MyUserName) + "' or mobile='" + MyUserName + "')";//2 serils登录,包括手机号,用户英文名等
        else if (LoginType.contains("WX")) SqlSTr = SqlSTr + " and WxOpenId='" + (MyUserPwd) + "'";//3微信openid登录 MyUserPwd=openid
        else if (!isNumberic(MyUserName,1)) SqlSTr = sql + " and TrueName='" + MyUserName + "'";//正则验证判断，不是数字，若字符串型则识别为姓名登录--杨汉信
        List<Map<String, Object>> dt1 = JdbcSql.GetDataSet(SqlSTr + " order by state,username"); int iRowCnt = dt1.size();
        if (iRowCnt > 1) { return "错误:您所输入的账号存在多条纪录，请换用别的登录方式！"; }
        else if (iRowCnt == 0) { if (!LoginType.contains("WX")) return "错误:您所输入的用户名不存在！"; }
        Map<String, Object> row = dt1.get(0);
        //if (row.get("IfLogin").toString().trim() != "是") { if (!LoginType.contains("WX")) return "错误:该用户暂时不允许登录系统，请联系管理员！"; }

        JdbcSql.ExecuteSQL("update xoauser set 登录错数=0,允许登录时间=now() where id=" + row.get("ID").toString());//清零登录错数
        String msg=PubUserLoginFunc(row, LoginType);
        if (msg.contains("该用户所在部门已失效")) return msg;//登录公用函数 =app+default用 xyx2019年7月1日 19:00:37
        if (LoginType.contains("app")) return "成功登录";//app登录
        if (!LoginType.contains("WX")&&Integer.parseInt(PwdLvl) < Integer.parseInt(get登录密级())) return "错误:密码密级过低，请修改密码";//系统跳转 改密码
        return "成功登录";
    }
    public static String getDtSessField(String cookiefield, String cookiepart)//读取会话表的 字段
    {//原先从cookie获取存储值,现在改为:如果session有,则从session获取,否则从dtSession数据库里面去取 2018年9月21日 08:43:52xyx
        if(!SessionGet(cookiefield).equals(""))return  SessionGet(cookiefield);
        //@Map<Object, Object> r1 = rh.hmget(rh.RedisDefaultKey + "login" + Common.Utf8Rquest("UserId"));// dtAppLoginSess.Get((context.Request["UserId"] ?? ""));
        //@if (r1 != null) return r1.get(cookiefield).toString();
        return "-1";
    }
    // 不带秘钥加密
    public static String md5(String text)  {
        // 加密后的字符串
        try{ return DigestUtils.md5DigestAsHex(text.getBytes("utf-8"));}
        catch (Exception e)
        { e.printStackTrace();return ""; }
    }
    /*第一次登录：传md5加密：userid+手机串号=str1
    后台带10位随机数+str1。Md5+|exp time+deivce_id+ip
    回传10位随机数++str1。Md5
    前台发送，后台比对exp time
           到期就返回超期*/
    public static String CreateUserToken(String UserId, String DeptId, String jiaose, String gw, String Department, String TrueName, String orgviewinit)
    {
        String UserTelEnc = Common.Utf8Rquest("UserTelEnc"), Token = "",Log1="1==",orgview="";
        Random rand = new Random();
        int radval =rand.nextInt(9000)+ 1000;  //rad.Next(10000000, 100000000);//用rad生成大于等于1000，小于等于9999的随机数；
        Token = md5(UserTelEnc+ radval );
        if (!jiaose.contains("普通学生")) orgview = JdbcSql.GetSHSL("SELECT GetChildDeptByID('" + DeptId + "','','','" + UserId + "')");//app登录把用户能够看到的部门(从bssvieworg+ 部门的chargeman+本部门)
        //@rh.AddLoginSess(rh.RedisDefaultKey + "login" + UserId, Token, Common.Utf8Rquest("deviceid"),  orgview, orgviewinit, jiaose, gw, Department, deptid, TrueName,600);
        return Token;
    }
    public static String getContextUserId()//获取username给handle用,xyx2020年4月28日 17:08:45
    {
        String UserId =SessionGet("UserName");
        if (UserId .equals("")) UserId = Common.Utf8Rquest("UserId");//如果是app则只传入userid,无session....如果是电脑端,则有session 2018年8月29日 16:04:25xyx
        return UserId;
    }
    public static String DynSetShowCtlByCol(String sTab, String RecId, String Act,String CondField,String DivPercent)//根据表配置显示字段
    {
        String Cond1 = "",Class1=""; if (!CondField.equals("")) Cond1 = " and ColName in ('" +Trim(CondField,",").replace(",","','") + "')" ;
        if ("xoareport".equals( sTab.toLowerCase()) && Cond1.replace(",", "") .equals("")) return "";
        String hei1="",ShowColList = "", strClear = "", sql = "SELECT Code编码,ColName,ColNameChn,CanNull,CanMod,CtrlType,SelValue,Hint,ColName+' \"'+ColNameChn+'\"' ColX FROM TwReportCol where TabName in('" + sTab + "') and ifnull(ColNameChn,'')<>'' "
                +" and (','+(ifnull(SeeUser,'0')+',') like '%,0,%' or ','+(ifnull(SeeUser,'0')+',') like '%," + getContextUserId() + ",%'   ) " + Cond1 + " order by Sort", ExpCols = "";
        List<Map<String, Object>> dt = JdbcSql.GetDataSet(sql);
        for (int j = 0; j < dt.size(); j++) ExpCols +=","+ dt.get(j).get("ColX").toString();
        ExpCols = "id 内部编号," + Trim(ExpCols,",");
        Map<String, Object> row = null;
        if ("ReportViewData".equals(RecId)) { RecId = ""; strClear = "<input type='button' class='btn btn-link inline' onclick='TextSetToNull(this)' value='重置'>"; }//如果是报表进来的,则有个清字
        if (!isStrEmpty(RecId))    row = JdbcSql.GetDbRow("select top 1 " + ExpCols + " from " + sTab + " where id=" + RecId);//修改       查看
        for (int j = 0; j < dt.size(); j++)
        {
            hei1 = ""; Class1 = "";
            Map<String, Object> r1 = dt.get(j);
            String val = "", l = r1.get("ColNameChn").toString(), WhereTmp = "", ColName = r1.get("ColName").toString();
            ShowColList += "<div class='col-sm-" + DivPercent + " bottomline'><div class='form-group'>";
            ShowColList += "<label class='col-sm-4 control-label'>" + l + "：</label><div class='col-sm-8'>";
            String s = dt.get(j).get("CtrlType").toString(), CanNull = "", CanMod = "", SelValue = dt.get(j).get("SelValue").toString();
            if (row != null) val = row.get(l).toString();
            else if (!s.contains("下拉框") || isStrEmpty(RecId)) val = SelValue;//isStrEmpty(RecId) 报表查询条件自定义时没有传入RecId 2019年2月20日 10:25:53 wyz
            if (dt.get(j).get("CanNull").toString() .equals( "0")) CanNull = " required='' ";
            if (dt.get(j).get("CanMod").toString() .equals( "0")) CanMod = " readonly=readonly ";
            String Hint = dt.get(j).get("Hint").toString(), Code编码 = r1.get("Code编码").toString().toLowerCase(), onclick="";
            if (!isStrEmpty(Hint)) Hint = " onmouseover=\"layer.tips('" + Hint + "', this);\" ";
            if (s.contains("下拉框"))//此处加入附件和部门等选择项
            {
                ShowColList += "<select style='width:80%' name=e" + ColName + " id=e" + ColName + " class='form-control input-sm'" + Hint + " />\n";
                String ddlNull = "select '<option value=-1>--请选择--</option>' union all ";
                if (s .equals( "下拉框固定值") || Code编码 .equals( "固定值")) for (String q : SelValue.split(",")) WhereTmp += "<option value='" + q + "'>" + q + "</option>\n";//foreach 替代为for
                else if (Code编码.contains("rzcode|")) WhereTmp = JdbcSql.GetStringList(ddlNull + "select '<option value='+''+'>'+''+'</option>' union select '<option value='+code+'>'+name+'</option>' from rzCode where state=case when '" + Act + "'='view' then state else 1 end and type='" + Code编码.split("\\|")[1] + "'").replace("|", "\n");//下拉框Code
            else if (Code编码.contains("ckcode|")) WhereTmp = JdbcSql.GetStringList(ddlNull + "select '<option value='+code+'>'+name+'</option>' from CK_Code where state=case when '" + Act + "'='view' then state else 1 end and type='" + Code编码.split("\\|")[1] + "'").replace("|", "\n");//下拉框Code
            else if (Code编码.contains("select ")&&Code编码.contains(" from")) WhereTmp = JdbcSql.GetStringList(Code编码).replace("|", "\n");//下拉框Code xyx2019年10月31日 17:45:50加入直接sql取code
            else WhereTmp = JdbcSql.GetStringList(ddlNull + "select '<option value='+code+'>'+code_name+'</option>' from xoacodelist where state=case when '" + Act + "'='view' then state else 1 end and code_type_name='" + SelValue + "'").replace("|", "\n");//下拉框Code
                if (!val.equals("")) ShowColList += WhereTmp.replace("value='" + val + "'", "value='" + val + "' selected").replace("value=" + val + "", "value=" + val + " selected") + "</select>\n";
                else ShowColList += WhereTmp.replace("value='" + val + "'", "value='" + val + "' selected") + "</select>\n";
            }
            else if (s.contains("文本区域"))
            {
                ShowColList += "<textarea  name='e" + ColName + "' id='e" + ColName + "' autocomplete=off style='width:80%'  " + onclick + CanNull + CanMod + " class='form-control input-sm inline' " + Hint + ">" + val + "</textarea>" + strClear + "";
            }
            else
            {
                if (s.contains("cx"))//查询框
                {
                    ShowColList += "<input type=hidden name=h" + ColName + " id=h" + ColName + " value='" + val + "' />\n";
                    onclick = " ReadOnly onclick=\"ZJselectList('" + Code编码 + "','h" + ColName + "','e" + ColName + "','" + "selectid='+$('#h" + ColName + "').val());\" onmouseover=\"layer.tips('点击选择" + l + "', this);\" \n";
                }
                else if (s .equals( "日期")) onclick = "onclick=\"laydate();\"";
                else if (s .equals( "时间" )&& SysTitle.contains("财经学院")) Class1 = "clockpicker";
                else if (s .equals( "时间")) onclick = "onclick=\"laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'});\"";
                else if (s .equals( "数字")) onclick = "onkeyup=\"if(isNaN(value))execCommand('undo');\" check_money='" + l + "请输入数字型'";
                ShowColList += "<input type=text name='e" + ColName + "' id='e" + ColName + "' autocomplete=off style='width:80%;" + hei1 + "' value='" + val + "' " + onclick + CanNull + CanMod + " class='form-control input-sm inline " + Class1 + "' " + Hint + " />" + strClear + "";//required=\"\"
            }
            ShowColList += "</div></div></div>";
        }
        return ShowColList + "`" + ExpCols;
    }
    /// <summary>
    /// Unicode转字符串
    /// </summary>
    /// <param name="source">经过Unicode编码的字符串</param>
    /// <returns>正常字符串</returns>
    public static String Unicode2String(String unicode)//&#x6d4b;&#x8bd5;&#x96c6;&#x56e2;101803  =测试集团101803
    {
        StringBuffer string = new StringBuffer();
        String[] hex = unicode.split("\\\\u");
        for (int i = 1; i < hex.length; i++) {
            int data = Integer.parseInt(hex[i], 16);// 转换出每一个代码点
            string.append((char) data);// 追加成string
        }
        return string.toString();
    }
    public static void Base64ToPic(String Base64Str, String FilePath)//base64de 字符串转存为图片文件png xyx2020年6月28日 19:32:55
    {

    }

    public static String getHttpRequestData(String urlP,String data) {//java中http协议调用get请求 // 首先抓取异常并处理
        String returnString = "1";
        try{
            /** 1 GET方式请求数据 start*/
            StringBuilder sb = new StringBuilder();
            sb.append(urlP);
            data = URLEncoder.encode(data,"UTF-8");
            sb.append(data);
            URL url = new URL(sb.toString());// 1  创建URL对象,接收用户传递访问地址对象链接
            // 2 打开用户传递URL参数地址
            HttpURLConnection connect = (HttpURLConnection) url.openConnection();
            connect.setRequestMethod("GET"); // 参数必须大写 // 3 设置HTTP请求的一些参数信息
            connect.connect();
            InputStream isString = connect.getInputStream();// 4 获取URL请求到的数据，并创建数据流接收
            BufferedReader isRead = new BufferedReader(new InputStreamReader(isString));// 5 构建一个字符流缓冲对象,承载URL读取到的数据
            String str = "";// 6 输出打印获取到的文件流
            while ((str = isRead.readLine()) != null) {
                str = new String(str.getBytes(),"UTF-8"); //解决中文乱码问题
//          System.out.println("文件解析打印：");//          System.out.println(str);
                returnString = str;
            }
            isString.close();// 7 关闭流
            connect.disconnect();
        }catch(Exception e){e.printStackTrace();}
        return returnString;
    }

}
